Massive Changes made by James Conwell. Begin Version 1.6 Jan. 6th 1997 *Enhanced Pronuciation of Speech. *Made numerous enhancements to program documentation. *Made numerous enhancements to the User Manual. My dad told me that he was playing a game of Chaos 1.5 and he had a magic bow with Range Boost. Everything was great. He then got _another_ magic bow so he thought "Oh cool! Now I can be even more powerful!" He cast magic bow and it removed his Range Boost! He was not happy. One thing that has always annoyed me is not knowing if I have line of sight diagonally adjacent to a generator or wall. I hate it when I try to cast a creature into a blank spot by a generator and then it says I can't because I don't have line of sight! Sometimes it works, sometimes it doesn't. It all depends on the quadrant. I have decided to alleviate this and add a new capability at the same time. Spells now have a CAST_LOS bit. Here is a complete list of things that I have changed in the cast.tex so far: *1. Added a new bit to CastInfo[] called CAST_LOS. This bit determines if a spell needs Line Of Sight or not. This solves the problem of casting creatures diagonally next to a generator or other large square object. It also allows the creation of spells that, for instance, have a range 3 but DON'T require line of sight. Cool! *2. I have modified the spell bits appropriately. Now all spells have thier CAST_LOS bit set except for spells with range of 0,1 or 15. So everything is functionally the same as it was. *3. CastInfo[] is now an array of UWORDS instead of UBYTES. *4. Made 1 change to DoCast and 2 changes to DoComputerCast to make the new CAST_LOS bit take effect. *5. Vengeance and Exorcise used to do the {\it exact} same thing. So I was going to change Exorcise to only be able to be cast on Undeads and bump the strength up to 7 to make up for this but there is no CAST_UNDEAD or CAST_UNDEAD_ONLY bit so I just raised the strength of Exorcise to 4. I just don't see the point in having 2 spells which do the exact same thing. Dark Power and Justice used to do the exact same thing. Now I have changed Justice to be 2 sets of 3-point attacks instead of 3 sets of 2-point attacks to add some variety. Thus Justice is now a bit less useful but Exorcise is a bit more useful so hopefully the play-balance is roughly the same as it was. *6. Magic Bow is now cumulative. Since magic bows are so rare (I've never had 2 of them in Chaos 1.5), I have set it to bump up the range by 1 on additional bows. That should be a pleasant surprise to anyone if they ever have 2 of them! *7. Destroy Wall now destroys PowerWalls also. *8. Made some adjustments to the TeX stuff. *9. Show numbers beside bar graphs. More Chaos User Manual Changes: *I made lots of little corrections. Then I did some embellishments: *1. I completely rewrote the intro. Hope you don't mind. Sorry it took so long but I just kept rereading it and editing it and rereading it and editing it... at least 30 times... *2. I embellished the description of the Roper, the combat section and the impurities. Subject: Freaky bug detected! I read over prog.tex thinking I was just going to word correct and spell correct the tex docs. This I did. They are now much better. Then I noticed something... #define GAMEROWNTSC 14 /* number of rows in a NTSC game */ #define GAMEROWPAL 11 /* the number of rows in a PAL game */ These 2 numbers are switched around! PAL is higher resolution than NTSC, thus it has more rows. PAL lores = 320x256. NTSC lores = 320x200. I couldn't believe that the game could even work with these 2 numbers switched around so I did some more research and found out why it was working... Another bug! Look at this from cmove.tex int weights[GAMEROWNTSC * GAMECOL]; See, it is using what is supposed to be the small value which would be too small for PAL users which would mean you would be using out-of-bounds subscripts in PAL mode BUT since you are the luckiest programmer I've ever seen, these 2 bugs cancelled each other out! Unbelievable! When *I* have 2 bugs in a program they produce 4 errors, not 0. I fixed the stuff in prog.tex and cmove.tex Also in cmove.tex: I fixed the deal where Independent Undeads never bothered to shoot. Word corrected some tex notes. I noticed something else that looks highly suspicious in prog.tex: #define NTSCMode (GfxBase->DisplayFlags & PAL) Shouldn't this be NTSC ? Yes. I will soon be adding a bunch of new stuff to the game and I don't want to be accused of being a memory hog so I have made 2 changes in prog.tex to save about 3k of ram. I changed const char creature_name[][CREATURE_SIZE] = { to const char *creature_name[] = { to produce a ragged array instead of a memory wasting rectangular array. Ditto for creature_speech. This has saved several k of ram! This also allowed me to delete the #define CREATURE_SIZE and SPEECH_SIZE since no part of the program ever uses either one. move.tex On a completely seperate subject, I made a small change to move.tex to allow me to see the _actual_ movement points available. Sometimes if you have 2 movement points, you can move diagaonally and then straight. Other times you can move diagonally once and then your move is over. I am hoping that I can understand the movement system better with the real movement points showing. I already understand it better now that I know that you are given a free .5 points at the beginning of the turn. That helps a lot, but I still don't get some things. *Added some prototypes to eliminate warnings with SASC6.0 *Show LOS required on Spell Info screen. Regarding using bitfields vs. NOT using bitfields: Well, here is everything I know about the subject: accessing board[i].char_stat.Life as a field of 5 bits vs. as a byte. I will ignore the C overhead since I don't know precisely what that is. At some point a move instruction will be generated to get the value then an and instruction will have to done to mask the appropriate bits. Given the notorious inefficiency of C, probably wastes an instruction fetching the mask, but who knows. bitfield method: move.b source, d0 move.b mask,d1 and.b d1,d0 lsr.b #x,d0 Byte method: move.b source,d0 So here we have 4 instructions to fetch the value vs. 1 instruction. Even if C is perfectly efficient, it WILL take at least twice as many instructions to fetch a bitfield as opposed to a byte. As for board[i].char_stat.Life vs. board[i].Life I would guess that the shorter version is quicker but the compiler could be clever enough that it wouldn't matter. I am assuming that both are bytes or both are bitfields. The reason bitfields are inherently slow is that all processors that I have ever studied are all designed to handle data in bytes, and/or words and/or longwords. Most processors have no bitfield instructions. Most of the processors that do have bitfield instructions (such 68020 to 68060) the bitfield instructions are much slower than a simple byte instruction (about 4x slower) It is often faster to avoid the bitfield instruction and just use a byte instruction and an and/or instruction. If you are really worried about speed then there is one simple thing you can do in the future to speed things up. Avoid >> and <<. Shifting a variable takes an extra instruction. So shifting and storing takes twice as long as just storing. However, it is even worse on the 68000. On the 68000 a shift of 1 takes as long as a regular instruction but it takes another 2 cycles for each additional shift. So when you shift by 3 ( << 3 ) you are adding around the equivalent of 2 simple instructions to the overall execution time in assembly code. Quite possibly more in C. The 68020 and higher processors have a "barrell shifter" which means they can shift any number of bits left or right in the same amount of time as a shift of 1. The only time I've really noticed chaos being slow is during computer movement on my Dad's 7.15909 Mhz A500. I noticed a lot of math being done in cmove.tex so that probably explains it. Multiplies take about 70 cycles and divides take about 158 cycles on the 68000. That's like 20 regular instructions. It basically seems ok to me on my A3000 and back when I used to play it on the A4000 it flew. Oh yes, I forgot one thing: Every time you access a bitfield it _must_ take at least TWO extra instructions to do that. Each instruction is 2 bytes. So if you have lots of code that accesses bitpacked fields then much or even all or even worse than all the space saved is wasted again. So right now every time we access char_stat.Life, there are 2 extra instructions being generated (at least). So if we access char_stat.Life 100 times in the program then that wastes 400 bytes and we only saved 3 bits per item in creature info. So if we have 200 objects (there aren't that many yet but there will be one day) then we saved 200*3 bits = 600 bits = about 75 bytes. A net defecit of 325 bytes. And it takes significantly more time; executing 3 instructions instead of 1. Chaos is currently 190284 bytes in size. To prove that I know what I am talking about, I will now change CreatureInfo to use all BYTES and then do a complete recompile.